#include "List.h"

void InitList(ListType *list)
{
    list->count = 0;
    list->head = 0;
    list->tail = 0;
}

void InitNode(ListNodeType* node)
{
    node->next = (ListNodeType *)0;
    node->prev = (ListNodeType *)0;
}

void InsertNodeAtBegin(ListType *list, ListNodeType *node)
{
    // node part
    node->next = list->head;
    node->prev = (ListNodeType *)0;

    // list part
    if (list->count == 0)
    {
        list->head = list->tail = node;
    }
    else
    {
        list->head->prev = node;
        list->head = node;
    }

    list->count++;
}

void InsertNodeAtEnd(ListType *list, ListNodeType *node)
{
    node->prev = list->tail;
    node->next = (ListNodeType *)0;

    // list part
    if (list->count == 0)
    {
        list->head = list->tail = node;
    }
    else
    {
        list->tail->next = node;
        list->tail = node;
    }

    list->count++;
}

/// @brief remove the first node of target list
/// @param list
/// @return return the node removed
ListNodeType *RemoveFirstNode(ListType *list)
{
    if (list->count == 0)
    {
        return (ListNodeType *)0;
    }

    ListNodeType *node = list->head;

    list->head = node->next;
    if (list->head == (ListNodeType *)0)
    {
        list->tail = (ListNodeType *)0;
    }
    else
    {
        list->head->prev = (ListNodeType *)0;
    }

    node->next = (ListNodeType *)0;
    list->count--;
    return node;
}

/// @brief remove the last node of target list
/// @param list
/// @return return the node removed
ListNodeType *RemoveLastNode(ListType *list)
{
    if (list->count == 0)
    {
        return (ListNodeType *)0;
    }

    ListNodeType *node = list->tail;

    list->tail = node->prev;
    if (list->tail == (ListNodeType *)0)
    {
        list->head = (ListNodeType *)0;
    }
    else
    {
        list->tail->next = (ListNodeType *)0;
    }

    node->prev = (ListNodeType *)0;
    return node;
}

ListNodeType *RemoveNode(ListType *list, ListNodeType *node)
{
    if (list->head == node)
    {
        list->head = node->next;
    }

    if (list->tail == node)
    {
        list->tail = node->prev;
    }

    if (node->prev)
    {
        node->prev->next = node->next;
    }

    if (node->next)
    {
        node->next->prev = node->prev;
    }

    node->prev = node->next = (ListNodeType*)0;
    list->count--;

    return node;
}